package br.com.faculdade.infrastructure.dao;

import br.com.faculdade.infrastructure.entity.Apartamento;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.TransactionPropagationType;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.log.Log;

/**
 * Classe de acesso aos dados de Apartamento
 * @author Kirmaier
 */
@AutoCreate
@Name("apartamentoDAO")
@Transactional(TransactionPropagationType.SUPPORTS)
public class ApartamentoDAO implements Serializable {

    @In
    private Session reservaDB;
    @Logger
    private Log log;

    public void alterar(Apartamento apartamento) {
        log.info("Alterar apartamento");

        reservaDB.saveOrUpdate(apartamento);
        reservaDB.flush();
    }

    public void cancelar() {
        log.info("Cancelando operação");

        reservaDB.flush();
    }

    public void excluir(Apartamento apartamento) {
        log.info("Excluir apartamento do banco");

        reservaDB.delete(apartamento);
        reservaDB.flush();
    }

    public Apartamento obterPorId(Integer apartamentoSelecionado) {
        log.info("Buscando apartamento por ID");

        return (Apartamento) reservaDB.get(Apartamento.class, apartamentoSelecionado);
    }

    public List<Apartamento> obterPorParametros(Integer paramNumeroApartamento, Integer paramNumeroQuartos, String paramDescricao, Integer tipoApartamento) {
        log.info("Obtendo apartamento por parametros");

        Criteria c = reservaDB.createCriteria(Apartamento.class);
        c.addOrder(Order.asc("numApart"));

        if (paramNumeroApartamento != null) {
            c.add(Restrictions.eq("numApart", paramNumeroApartamento));
        }
        if (paramNumeroQuartos != null) {
            c.add(Restrictions.eq("numQuartosApart", paramNumeroQuartos));
        }
        if (paramDescricao != null && !paramDescricao.isEmpty()) {
            c.add(Restrictions.ilike("descricaoApart", paramDescricao, MatchMode.ANYWHERE));
        }
        if (tipoApartamento != null) {
            c.createAlias("tipoApartamento", "tipoApartamento");
            c.add(Restrictions.eq("tipoApartamento.idtipo", tipoApartamento));
        }

        return c.list();
    }

    public List<Apartamento> obterPorTipo(Integer tipoApartamento) {
        log.info("Buscando apartamentos por tipo");

        Criteria c = reservaDB.createCriteria(Apartamento.class);
        c.addOrder(Order.asc("numApart"));

        if (tipoApartamento != null) {
            c.createAlias("tipoApartamento", "tipoApartamento");
            c.add(Restrictions.eq("tipoApartamento.idtipo", tipoApartamento));
        }

        return c.list();
    }

    public List<Apartamento> obterTodos() {
        log.info("Buscando todos");

        Criteria c = reservaDB.createCriteria(Apartamento.class);
        c.addOrder(Order.asc("numApart"));

        return c.list();
    }

    public void salvar(Apartamento apartamento) {
        log.info("Persisti o objeto no banco");

        reservaDB.save(apartamento);
        reservaDB.flush();
    }
}
